查看原文
其他

详解以太坊:关于交易机制

岳小鱼 岳小鱼 2023-04-05


Web3世界依旧处于早期的阶段,因此在研究这个领域时,不可避免地要了解很多关于技术层面的东西。
对于没有技术基础的行业新人来说,去理解底层技术会非常困难,然而收益却没有那么大。
就像当我们去研究黄金时,我们不需要去钻研黄金的化学分子构成,而是会研究黄金的基本属性、市场价值、流通体系等等。
因此,本系列文章将从一个产品经理的视角出发,输出“用户体验友好”的内容,尽量不去深究技术细节,而是从整体架构、运作机制等方面剖析以太坊。
本文是《详解以太坊》系列文章的第2篇,之前的文章请参见:
详解以太坊:整体框架


数据层是公链的最底层,里面包含了区块链底层的密码学原理、数据结构。
区块链本质上就是一个“全球化大账本”,每个人都可以查看和记录交易信息。
因此,我们需要理解私钥、公钥、地址到底都是什么,以及它们有着怎样的关系。
只有了解了这一层,才能明白区块链的核心能力以及与传统金融体系的差别。
01 基础概念
无论是比特币网络,还是以太坊,每一条区块链我们都可以把它当做一个全球化的“大账本”,具体形式就是一个“大表格”,按照顺序将交易信息记录到这个大表格中。
在这个大账本中,记录了我们的每一笔交易信息。
类比现实生活中的银行,我们如果想要和他人交易,需要以下步骤:
(1)创建一个银行卡账户,然后设置密码
在区块链中,我们是先通过随机数生成器生成一个私钥,这个私钥就是银行卡密码,然后再通过私钥生成公钥,这个公钥就是银行账户,公钥会再生成地址,这个地址就是银行卡账号。
这个创建过程与现实世界中的银行是相反的。
但是和银行一样,即使别人知道你的公钥和地址(银行账户和银行卡账号),也无法获取你的私钥(银行卡密码)。
(2)向另一个银行卡账号转账
如果要向另外一个银行账户转账,你需要先知道对方的银行卡号,然后输入转账金额(不能大于自己账户的金额),接下来则需要输入银行卡密码,验证通过后就可以发起转账了。
与这个过程类似,唯一的差别是你不需要将你的密钥(也就是银行卡密码)告诉任何人或任何组织,仅需要通过私钥进行数字签名即可。
在传统金融体系中,银行存储了你的银行卡密码并在转账时进行校验,这个银行就是一个中心化的中介。
但在区块链世界中,你的私钥只有你自己知道和保存,且不会再在任何场景中出现,只需要一个算法证明你拥有自己的私钥即可。
(3)银行账户挂失
如果你的银行卡丢失了或者银行卡密码丢失了,你可以将这个银行账户冻结,或者向银行证明你的身份后,重置密码即可。
但在区块链世界中,你的私钥丢失了就再也找不回来了,也没有人可以冻结你的账户或者修改你的密码。
了解了这几个名词概念后,我们具体看下各个组件的详细介绍。
1.关于私钥
我们发现私钥这个东西至关重要,那私钥是怎么生成的呢?
私钥是通过随机数生成器生成的,随机数范围要足够大,目前主要是在1至2的256次方之间。
有的人可能会担心自己的私钥会不会和他人冲突,但是2的256次方有多大呢?
这个数量级和我们已知宇宙中所有原子的总数差不多。
这个数字在十进制中几乎是10的77次方,也就是说,是个77位数。在可见的宇宙中,人们估计一共有10的80次方个原子,因此我们几乎有足够的私钥给宇宙中的每个原子了。
所以也不用担心自己的私钥会和别人的私钥相撞。
2.关于公钥
公钥是通过对私钥使用椭圆曲线的乘法运算得来的,而这个乘法运算基本上是不可逆的:K=k*G。
其中k是私钥,G是一个常量点,称为生成点,K是计算得来的公钥,*是椭圆曲线函数的乘法运算符号。这与普通乘法运算的规则是不同的。
每个以太坊公钥都是椭圆曲线上的一个点,也就是说,每个公钥都是一组x、y坐标,这个坐标正好满足椭圆曲线方程。
椭圆曲线乘法就是我们在密码学中提到的“单向”函数:它很容易从一个方向(乘法)进行计算,但是不可能采用反向(除法)的方式计算。
这意味着通过私钥计算获得公钥是非常容易的,但是你不能反过来通过公钥算出它所对应的私钥。
而地址则是将公钥通过单向哈希函数Keccak-256计算而来。
因此,公钥以及通过公钥生成的地址是可以公开的,并且可以通过地址来进行转账。
3. 关于哈希函数
相比加密算法,单向哈希函数在现代密码学中才是主力军,也是数字货币运作的基石。
哈希函数是一个可以将任意长度数据映射成固定长度数据的数学函数,。
加密哈希函数是一种单向的哈希函数,可以将任意长度的数据映射为固定长度的比特序列。
加密哈希函数的五个特性:
(1)确定性:同样的输入信息总是会产生相同的输出哈希。
(2)可验证性:计算任意输入信息量的哈希运算非常高效(线性的计算性能)。
(3)无关联性:对于输入消息的微小改变(哪怕是只改变一个比特)都会对输出结果的哈希造成巨大的变化,而且这样的变化与之前的消息之间没有任何关联性。
(4)不可逆性:从哈希反向计算得出输入的原始信息是不现实的,只能通过暴力穷举式的尝试。
(5)碰撞保护性:几乎不可能找到能够得到同一个哈希输出的两个不同信息。
正是由于这些特性,哈希函数被用来通过公钥生成对应的地址、通过私钥进行数字签名。
4.关于代币
区块链上的代币是指基于区块链的一种抽象资产,可以被持有并且用来代表资产或权益。
代币可以提供多种功能,很多情况下这些功能互相重叠。例如,一个代币既可以代表一个投票的权利,同时又可以代表针对特定资源的访问权和所有权。
代币的使用方式包括:货币、资源、资产、访问权限、权益、投票权、收藏品、身份等。
数字货币只是代币的第一个应用场景而已,因此目前也只有“比特币”可以被称为数字货币,是一种通用货币,而大多数的其他数字资产只能在特定场景下进行使用,和游戏厅中“游戏币”类似,只能在特定的场景中使用。
根据可替代性,代币可以分为同质化代币和非同质化代币。
(1)代币的可替代性是指当我们把一个代币的基本单元互相交换时,并不影响它的价值或功能,因此这种代币就是同质化的,比如你的100块钱和其他人的100块钱价值是一样的;
(2)不可替代性代币是指那些代表了独特的有形或无形资产的代币,因此这些代币之间不可以互相替代,被称为非同质化代币,典型的就像你的一个珍藏版邮票和其他人的邮票是不一样的。
在以太坊中,目前有三种代币协议类型:ERC20是同质化代币,ERC721和ERC1155是非同质化代币。
需要注意,以太坊账户的以太币余额在协议级别处理,而以太坊账户的代币余额在智能合约级别处理,因此以太币和其他代币是不同的。
现在大多数的代币都是基于ERC20标准,这个需求提议最终成为以太坊的标准EIP-20,但是大多数人仍旧喜欢采用ERC20这个叫法。
ERC20是可替代性代币的标准,意味着ERC20代币的不同单元之间是可以互相交换的,代币并没有独特的属性。
ERC20标准定义了通过合约实现代币的通用接口,兼容此标准的所有代币都可以采用相同的方式被访问和使用。
ERC20代币标准只是跟踪每一个账户的最终余额,并不跟踪每一个单位的代币是从何而来的。
ERC721方案是针对不可替代物代币的标准,也称为契约代币。
不可替代性代币用于跟踪一个独特事物的所有权。
ERC20只会记录所有者,跟踪每个所有者的余额;而ERC721则会记录每一个代币的ID(因为每一个代币都是不同的),跟踪每个代币ID及其所有者。
02 交易
交易是由账户发出的经过签名的消息,通过以太坊的网络传播,由矿工或验证节点记录在区块链网络上。
平均而言,每一个以太坊节点大约维护了至少13个跟它直接相连的其他节点,称为邻居。
每一个邻居节点都会在收到交易数据包后立刻进行验证,验证通过后会广播给其他邻居。
因此,交易就像是水中的波纹一样,在整个网络中迅速传播开,直到所有节点都收到了一份交易的副本。
在短短几秒钟的时间内,一个以太坊交易就能到达全球范围内所有的以太坊节点,这也就是P2P网络(点对点数据传输的网络)。
交易信息中会包含我们自己的账户地址、对方的账户地址、交易的金额、交易手续费等等信息。
我们具体看下一个交易消息中覆盖的数据结构:
(1)nonce:一个序列编号,由构建这个交易的账户提供,防止交易的重放攻击
(2)gas price:交易发起方愿意支付的gas价格
(3)gas limit:交易发起方愿意为这个交易支付的最大gas数量
(4)recipient:目标地址
(5)value:发送给目标地址的以太币的数量
(6)data:附在交易中可变长度的数据
(7)v,r,s:由构建交易的账户提供的椭圆曲线签名的三个组成部分
注意:数据结构中没有from地址、区块编号、交易ID,这些数据都是从交易数据中推算出来的。
我们具体看下这些数据类型代表的具体含义以及逻辑。
1.关于nonce
什么是nonce?
nonce是一个数值,等于某个地址发出的交易数量,当某个地址与智能合约关联时,是这个地址所创建的合约数量。
它是通过计算发送方地址已经确认的交易数量而动态计算的。
本质上,nonce就是发起交易那个地址目前所有已确认交易(即链上交易)的计数器。
在比特币中,nonce主要用于调整PoW挖矿的难度,而在以太坊中,除了调整挖矿难度外,在账户的每笔交易中也都存在一个nonce。
这个nonce是一个连续的整数,在每个账户发送交易时所产生,其主要设计目的是为防止双花攻击(即同一笔钱被花费了两次)。
如果交易数据中包含nonce值,那么每一笔交易都是唯一的,即便是多次向同一个收件人地址发送相同数量的以太币交易也是如此。因此,通过将递增的随机数作为交易的一部分,任何人都没有办法“复制”你已经完成的付款。
举个例子,你发送的第一笔交易有一个随机数,假设是3,而发送的另一笔交易将具有下一个随机数(如4)。因此,nonce为4的这笔交易将被忽略,直到nonce值为0到3的交易已经被处理,即便它是先被节点接收到的。
以太坊所有的交易都是基于 account ,不同于基于utxo的比特币,因此需要对每次交易都按顺序记录,nonce值就是这个顺序,nonce 是交易原始地址的属性。它不存储在以太坊区块链上,而是通过计算从一个地址发送的交易数量来计。
为了防止交易重复进行,以太坊要求一个账户的每笔交易必须有一个nonce数值,每个节点将根据计数顺序严格执行来自一个用户的交易。
nonce值从0开始递增,每发送一笔交易,nonce便加1。
只有当前面nonce值较小的交易处理完成之后才会处理后面nonce值较大的交易。
以太坊处理nonce的规则:
(1)当nonce小于之前已经有交易使用的nonce值,交易会被拒绝;
(2)当nonce大于当前应该使用的nonce时,交易会一直处于队列之中进行等待,交易依次执行,直到补齐中间间隔的nonce值,才可以执行。
(3)当有一笔处于pending(待处理)状态的交易,新的一笔处于pending状态的交易与其拥有相同的nonce值,如果新交易的gas price太小,无法覆盖原来pending状态的交易,如果新交易的gas price高于原交易的110%,则原交易会被覆盖掉。
从以太坊的这个机制中可以看到,Nonce会导致堵车问题和并发问题。
如果你按顺序创建了一系列交易,但其中一个没有得到确认,那么之后的所有交易都会“堵”住,等待这个缺失的交易。
如果某个交易的nonce值不对,或者没有足够的gas,就很可能会导致这样的堵车现象。
处理并发是计算机科学中的一个难题,有时会在意想不到的情况下出现并发问题,尤其是在去中心化的、分布式的、实时处理的系统中,例如以太坊。
2.关于gas
gas这个单词直接翻译过来就是“汽油”,这个单词其实非常形象,以太坊作为一个世界计算平台,当你需要在这个平台上进行运算时,需要一定费用,也就是“燃料”。
gas并不是以太币,它是一种独立的虚拟货币,跟以太币之间存在汇率关系。
gas独立于以太币,是为了在以太币价格大幅度波动的情况下,仍旧保护系统的灵活性。
交易中的gasPrice字段允许交易的发起方设定针对gas的汇率,gasPrice越高,交易被确认的速度也越快。
也就是说,你愿意花费更多的费用让矿工或节点优先处理你的交易。
注意:gasPrice最低可接受的值是零,这意味着可以生成完全不包含任何手续费的交易。
gasLimit表示这个交易的发起方为了完成交易所愿意支付的最大gas数量。
当你发出交易时,验证交易的第一个步骤就是确保发起交易的账户中有足够的以太币来支付对应的gas费用(即gasPrice*gas)。但是这时并不会从账户中直接扣除gas,而是直到交易执行结束后才会扣除。
3.关于recipient
recipient就是交易的接收方。
以太坊不会验证接收方地址,任何一个20字节的值都会被认为是正确的。
向一个错误的地址发送交易可能会导致以太币被销毁,使其永远无法被访问(不可被花费),这是因为大部分地址没有已知的私钥,也就无法生成签名去使用它。
因此,你在向对方的“银行卡账号”转账时,千万不能输错,否则这笔钱就会丢失了。
4.关于value和data
只包含value的交易是支付操作,只包含data的交易是针对合约的调用。
既没有value也没有data的交易也许只是为了浪费gas,但也是允许的。
03 钱包
聊到交易,自然要谈一下钱包。
知道了交易的密码学原理以及交易信息的构成之后,我们需要知道资产是怎么被管理的。
在Web3世界中,我们经常会听到“钱包”这个词,钱包可以说是Web3世界的入口,那到底什么是钱包呢?
其实,钱包里面并没有放钱,就像我们现实生活中的钱包,钱包中放的是更多是银行卡、钥匙等物品。
对于Web3世界也一样,钱都保存在区块链上,钱包这个词特指用来存储和管理用户密钥(即银行卡密码)的系统。
每个钱包都包含一个密钥管理系统,有的钱包,密钥管理系统是唯一的模块;而有的钱包,可能在这个基础上有更广泛的功能,比如作为去中心化应用的入口。
1.钱包的分类
在设计钱包时,一个关键的考量就是权衡便利性与隐私性。
最方便的以太坊钱包就是单一私钥和对应地址,在每一个场合中都使用同一个地址。但是,这样的解决方案就是隐私上的恶梦,因为任何人都可以轻松跟踪你的交易并将它们关联起来。
为每一笔交易都使用一个新私钥对隐私性来说当然是最好的了,但这样就很难管理私钥。
最佳的平衡点并不容易把握,但这也解释了为什么钱包的设计是最重要的。
钱包主要分为两类:
第一类是非确定性钱包,其中保存的每一个私钥都是通过不同的随机数相互独立地生成的。私钥之间没有任何关联。这类钱包被称为JBOK(Just a Bunch Of Keys)钱包。
第二类钱包是确定性钱包,其中所有的密钥都是从一个主密钥衍生而来的,这个主密钥就是种子密钥。这类钱包中所有的密钥之间都存在关联关系,如果获得了“种子密钥”,则可以重新生成所有密钥。
最常用的派生方法是使用一个类似树形的结构,我们称之为层级式确定性(hierarchical deterministic)钱包,或简称为HD钱包。
为了让确定性钱包在对抗数据丢失事件(比如手机失窃)时稍微安全一点,我们一般会将种子编码为一个英文词列表(当然也可以使用其他语言),你可以将其抄写下来并在意外发生时使用,这样的列表就是钱包助记词。
在使用以太坊时,避免重用密钥是保护隐私的好办法,即每次接收资金时都使用新地址(这样也需要新私钥)。
对于非确定性钱包,要备份不同的随机密钥非常麻烦,而使用确定性钱包则比较便捷,只需要种子密钥即可。
目前市面上的去中心化钱包,基本都是HD钱包。
HD钱包中的每一个密钥都是从一个种子密钥派生而来的,这使得即使包含了数千甚至上百万密钥的HD钱包的备份、恢复、导入、导出都变得容易,只需要在钱包之间迁移用来生成种子密钥的助记词即可。
HD钱包的一个非常有用的特性就是可以从父公钥派生子公钥,而这个过程并不需要使用私钥。因此有两种方式可生成子公钥:既可以使用子私钥,也可以使用对应的父公钥。
因此,扩展的公钥可以用来生成HD钱包对应分支中所有的公钥。只在服务器或者应用中部署公钥以作为扩展公钥,而不再需要私钥。
这样就保障了私钥的安全性。

2.关于种子密钥和助记词
要安全地备份和恢复私钥有很多种办法。当前最受好评的方法是使用一组有序的单词,只要可以将这些单词组成正确的序列,就可以重建出一把独一无二的私钥。
这就是我们常说的助记词,这一方法由BIP-39标准化了。
很多以太坊钱包软件(包括其他数字货币的钱包软件)都使用这个标准,支持使用助记词进行种子密钥的导入导出和备份恢复。
目前钱包的种子密钥派生密钥的行业标准有四个:
· 基于BIP-39的助记词标准
· 基于BIP-32的层级式确定性钱包标准
· 基于BIP-43的多用途层级式确定性钱包结构
· 基于BIP-44的多币种和多账户钱包
这些标准构成了一系列互相关联的技术,是大多数数字货币钱包实现的事实标准。
我们具体来看下助记词标准BIP-39:
(1)生成助记词过程:助记词由钱包根据BIP-39所定义的标准流程自动生成,钱包从随机源获取一个随机数,然后添加校验码,再把这个数字映射为一串英文单词。

(2)从助记词生成种子密钥过程:助记词也可以反向生成种子密钥。
需要注意,BIP-39标准允许用户在生成种子密钥的过程中使用可选密码。
如果用户没有设定密码,那么默认使用字符串"mnemonic"进行助记词的密钥扩展运算,生成一个特定的512比特的种子密钥。
实际上,给定一组助记词,每一个密码都会导致不同的种子密钥。
在BIP-39中,没有正确或者错误的密码。任何密码结合助记词都对应着一个钱包,如果这个钱包之前没有使用过,那么它就是空的。

3.关于冷钱包
去中心化钱包根据是否联网,可以分为热钱包和冷钱包。
由于冷钱包不联网,隔绝了网络攻击的风险,因此安全性要高于热钱包。
冷钱包没有联网,那是怎么数字签名和发送交易的呢?
简单来说,私钥保存在硬件钱包中,公钥放在网上,这样用户就可以创建收款地址,同时对应的私钥被安全地保存在离线环境中。
为了花费自己的资产,用户可以使用私钥在线下或者硬件钱包设备上签名对应的交易。
那具体怎么签名的呢?
通常交易的创建、签名和广播都是在一个操作中完成的,但也可以分开执行。
为什么要把交易的签名和广播分开处理?主要原因是安全。
把交易的签名和广播分开处理的做法称为离线签名(联网的设备和未联网的设备分别处理),这是一种非常常见的安全手段。
用于签名的计算机上保存账户的私钥,用于广播交易的计算机必须连接在互联网上,并且运行以太坊客户端。

(1)创建交易:为当前状态的账户通过在线计算机创建一个未签名的交易,可以检索该账户当前的nonce和余额。
(2)签名:将未签名的交易转移到“空气隔离”的离线设备以便进行签名,如通过QR码或USB闪存设备。
(3)广播交易:将已经签名的交易转移回在线设备,以便在以太坊区块链上进行广播,如通过QR码或USB闪存设备。
在“空气隔离”的系统中根本就没有网络连接,计算机完全隔离于任何网络环境,这种计算机就是冷钱包。
最后
本文主要分为三部分,分别介绍了密码学原理(私钥公钥地址)、交易的数据结构以及钱包的运作原理,这些概念组成了区块链的数据层。
通过数据层的介绍,我们发现我们可以直接掌握自己的资产,直接与他人交易并看到资金流的流向,不需要通过任何第三方(比如银行)作为中介进行处理,这正是区块链与传统金融体系的关键不同之处。
通过区块链技术,真正实现了“财产确权”,让财产掌握在每个个体手中。
后续,我们将继续介绍以太坊的第二层,即共识层。


推荐阅读

详解以太坊:整体框架
公链生态纵览:浅析现有公链市场格局


··················END··················
你好,我是岳小鱼,一名在路上的产品经理。
会和你聊聊职场和产品经验,也会漫谈生活、电影、读书。
希望我们能一起交流进步。


您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存